package com.wlps.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.wlps.bo.OrderBO;
import com.wlps.bo.RecepitBo;
import com.wlps.contant.Contant;
import com.wlps.entity.*;
import com.wlps.mapper.CommodityWarehouseMapper;
import com.wlps.mapper.MissionListMapper;
import com.wlps.result.ResultPageVo;
import com.wlps.result.ResultUtils;
import com.wlps.result.ResultVo;
import com.wlps.service.*;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.wlps.vo.ReceiptVo;
import com.wlps.vo.sendcenter.commodity.FirstClassificationVo;
import com.wlps.vo.warehousecenter.pickup.MissionListCommodityWarehouseVo;
import com.wlps.vo.warehousecenter.pickup.MissionListVo;
import com.wlps.vo.warehousecenter.pickup.PickupVo;
import com.wlps.vo.warehousecenter.warehoused.WarehousedVo;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.InitializingBean;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.scheduling.annotation.Async;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import javax.annotation.Resource;
import java.util.*;
import java.util.concurrent.TimeUnit;
import java.util.stream.Collectors;
import java.util.stream.Stream;

/**
 * <p>
 * 任务单表(mission_list)
 * (1.当任务单状态为已分配时，不可以再进行该用例。)
 * (2.当订单形成任务单，分配具体执行任务的配送员。) 服务实现类
 * </p>
 *
 * @author ZWYZY
 * @since 2020-07-31
 */
@Service
@Slf4j
@Transactional(rollbackFor = Exception.class)
public class MissionListServiceImpl extends ServiceImpl<MissionListMapper, MissionList> implements IMissionListService, InitializingBean {
    @Autowired
    RedisTemplate redisTemplate;

    @Autowired
    CommodityWarehouseMapper commodityWarehouseMapper;

    @Autowired
    IOrderService orderService;
    @Autowired
    IOrderRecordService orderRecordService;

    @Autowired
    ICommodityOrderService commodityOrderService;
    @Resource
    ICommodityService commodityService;
    @Resource
    MissionListMapper missionListMapper;
    @Override
    public void afterPropertiesSet() throws Exception {
        initMissionListVo();
        initWarehousedVo();
    }

    /**
     * 初始化缓存
     */
    void initMissionListVo() {
        List<MissionListVo> missionListVoList;
        if (!redisTemplate.hasKey(Contant.MISSIONLISTVOS_KEY)) {
            missionListVoList = baseMapper.selectMissionListVoList();
            redisTemplate.opsForValue().set(Contant.MISSIONLISTVOS_KEY, missionListVoList,5, TimeUnit.MINUTES);
            log.info("初始化所有任务单（非退货任务单）-------存入缓存数据");
        }


    }

    /**
     * 初始化缓存
     */
    void initWarehousedVo() {
        List<WarehousedVo> warehousedVoList;
        if (!redisTemplate.hasKey(Contant.WAREHOUSEDVOS_KEY)) {
            warehousedVoList = baseMapper.selectWarehousedVoList();
            redisTemplate.opsForValue().set(Contant.WAREHOUSEDVOS_KEY, warehousedVoList,5,TimeUnit.MINUTES);
            log.info("初始化所有退货任务单-------存入缓存数据");
        }


    }


    @Override
    public ResultPageVo<List<MissionListVo>> getMissionList(int pageNum, int pageSize, Long id) {
        initMissionListVo();
        //总条数
        int count;
        //偏移量
        int fromNum;
        //终止量
        int toNum;
        List<MissionListVo> missionListVoList = (List<MissionListVo>) redisTemplate.opsForValue().get(Contant.MISSIONLISTVOS_KEY);
        if (id == null) {
            //不是条件查询，redis
            count = missionListVoList.size();

        } else {
            Stream<MissionListVo> stream = missionListVoList.stream();
            stream = stream.filter(x -> x != null && id.equals(x.getId()));
            missionListVoList = stream.collect(Collectors.toList());
            count = missionListVoList.size();
        }
        //当前页从第几条开始查
        fromNum = pageSize * (pageNum - 1);
        if (fromNum >= count) {
//            sysUserList=null;
        } else {
            //当前页最后第几条
            toNum = fromNum + pageSize >= count ? count : fromNum + pageSize;
            missionListVoList = missionListVoList.subList(fromNum, toNum);
        }


        //分页返回值封装
        ResultPageVo resultPageVo = new ResultPageVo("响应成功", 200, (long) pageSize, (long) pageNum, (long) count, missionListVoList);
        return resultPageVo;
    }

    @Override
    public ResultPageVo<List<WarehousedVo>> getWarehousedVo(int pageNum, int pageSize, Long id) {
        initWarehousedVo();
        //总条数
        int count;
        //偏移量
        int fromNum;
        //终止量
        int toNum;
        List<WarehousedVo> warehousedVoList = (List<WarehousedVo>) redisTemplate.opsForValue().get(Contant.WAREHOUSEDVOS_KEY);
        if (id == null) {
            //不是条件查询，redis
            count = warehousedVoList.size();

        } else {
            Stream<WarehousedVo> stream = warehousedVoList.stream();
            stream=stream.filter(x -> x != null && id.equals(x.getId()));
            warehousedVoList = stream.collect(Collectors.toList());
            count = warehousedVoList.size();
        }
        //当前页从第几条开始查
        fromNum = pageSize * (pageNum - 1);
        if (fromNum >= count) {
//            sysUserList=null;
        } else {
            //当前页最后第几条
            toNum = fromNum + pageSize >= count ? count : fromNum + pageSize;
            warehousedVoList = warehousedVoList.subList(fromNum, toNum);
        }

        //分页返回值封装
        ResultPageVo resultPageVo = new ResultPageVo("响应成功", 200, (long) pageSize, (long) pageNum, (long) count, warehousedVoList);
        return resultPageVo;
    }

    @Override
    public ResultVo editPickupVo(PickupVo pickupVo) {
        if (((List<MissionListVo>) redisTemplate.opsForValue().get(Contant.MISSIONLISTVOS_KEY)).stream().filter(x -> x != null && pickupVo.getId().equals(x.getId())).count() == 0) {
            return ResultUtils.error("任务号查询不到，请输入正确的任务号，亲", 90000);
        }

        MissionList missionList = baseMapper.selectById(pickupVo.getId());
        if (missionList.getTaskType() != 0) {
            return ResultUtils.error("当前不是送货任务单,请重新输入送货任务单号", 90002);
        }
        if (missionList.getTaskStatus() == 0) {
            return ResultUtils.error("已完成领货，无需重复确认领货", 90003);
        }
        missionList.setTaskStatus(0);
        baseMapper.updateById(missionList);


        List<MissionListCommodityWarehouseVo> mcwVo = baseMapper.selectMissionListCommodityWarehouseVo(pickupVo.getId());
        mcwVo.stream().forEach(x -> {
            Long currentNumber = x.getCommodityWarehouse().getCurrentNumber();
            Long amountNumber = x.getCommodityMissionList().getAmountOfGoods();
            x.getCommodityWarehouse().setCurrentNumber(currentNumber - amountNumber);
            commodityWarehouseMapper.update(x.getCommodityWarehouse(), new QueryWrapper<CommodityWarehouse>().lambda().eq(CommodityWarehouse::getWarehouseId, x.getCommodityWarehouse().getWarehouseId()).eq(CommodityWarehouse::getProductName, x.getCommodityWarehouse().getProductName()).eq(CommodityWarehouse::getCommodityId, x.getCommodityWarehouse().getCommodityId()));

        });

        Order order = orderService.getById(missionList.getOrderId());
        order.setOrderStatus(3);

        OrderRecord orderRecord = new OrderRecord();
        orderRecord.setOrderId(missionList.getOrderId());
        orderRecord.setOrderStatus(3);
        orderRecord.setOrderType(order.getOrderType());
        orderRecord.setOperator(pickupVo.getName());
        orderRecord.setOperatingTime(pickupVo.getDateTime());
        orderRecordService.save(orderRecord);
        missionListVoCache();
        return ResultUtils.success("领货成功");
    }

    @Override
    public ResultVo editWarehousedVo(Long id) {

        if (((List<MissionListVo>) redisTemplate.opsForValue().get(Contant.MISSIONLISTVOS_KEY)).stream().filter(x -> x != null && id.equals(x.getId())).count() == 0) {
            return ResultUtils.error("任务号查询不到，请输入正确的任务号，亲", 90000);
        }
        MissionList missionList = baseMapper.selectById(id);
        if (missionList.getTaskType() != 2) {
            return ResultUtils.error("当前不是退货任务单,请重新输入退货任务单号", 90001);
        }
        if (missionList.getTaskStatus() == 4) {
            return ResultUtils.error("已完成退货，无需重复确认退货", 90004);
        }
        missionList.setTaskStatus(4);
        baseMapper.updateById(missionList);


        List<MissionListCommodityWarehouseVo> mcwVo = baseMapper.selectMissionListCommodityWarehouseVo(id);
        mcwVo.stream().forEach(x -> {
            Long currentNumber = x.getCommodityWarehouse().getCurrentNumber();
            Long amountNumber = x.getCommodityMissionList().getAmountOfGoods();
            x.getCommodityWarehouse().setCurrentNumber(currentNumber + amountNumber);
            commodityWarehouseMapper.update(x.getCommodityWarehouse(), new QueryWrapper<CommodityWarehouse>().lambda().eq(CommodityWarehouse::getWarehouseId, x.getCommodityWarehouse().getWarehouseId()).eq(CommodityWarehouse::getProductName, x.getCommodityWarehouse().getProductName()).eq(CommodityWarehouse::getCommodityId, x.getCommodityWarehouse().getCommodityId()));

        });
        Order order = orderService.getById(missionList.getOrderId());
        order.setOrderStatus(5);

        OrderRecord orderRecord = new OrderRecord();
        orderRecord.setOrderId(missionList.getOrderId());
        orderRecord.setOrderStatus(5);
        orderRecord.setOrderType(order.getOrderType());
//        orderRecord.setOperator(pickupVo.getName());
        orderRecord.setOperatingTime(new Date());
        orderRecordService.save(orderRecord);
        missionListVoCache();
        warehousedVoCache();
        return ResultUtils.success("退货成功");
    }

    @Override
    public ReceiptVo recepitById(long id) {
        ReceiptVo receiptVo = missionListMapper.recepitById(id);
        if (receiptVo==null)
        {
            throw new RuntimeException("不存在该任务单或者该任务单没有指定配送员去配送无法打印订单");

        }
        List<OrderBO> o = (List<OrderBO>) redisTemplate.opsForValue().get(String.valueOf(id));
        List<Integer> collect = o.stream().map(OrderBO::getNumber).collect(Collectors.toList());
        Collection<Commodity> commodityOrders = commodityService.listByIds(collect);
        Iterator<OrderBO> iterator = o.iterator();
        List<RecepitBo> list=new ArrayList<>();
        commodityOrders.forEach(commodityOrder -> {
            RecepitBo recepitBo = new RecepitBo();
            recepitBo.setPrice(commodityOrder.getUnitPrice());
            recepitBo.setProductName(commodityOrder.getProductName());
            if(iterator.hasNext())
            {
                OrderBO next = iterator.next();
                recepitBo.setNumber(next.getNumber());
                recepitBo.setId(next.getCommodityId());
            }
            list.add(recepitBo);
        });
        receiptVo.setReceptBo(list);
        return receiptVo;
    }

    /**
     * 更新缓存
     */
    @Async
    public void missionListVoCache() {
        List<MissionListVo> missionListVoList;
        missionListVoList = baseMapper.selectMissionListVoList();
        redisTemplate.opsForValue().set(Contant.MISSIONLISTVOS_KEY, missionListVoList,5,TimeUnit.MINUTES);

        log.info("所有任务单（非退货任务单）-------更新缓存数据");
        List<CommodityWarehouse> commodityWarehouseList = commodityWarehouseMapper.selectList(null);
        redisTemplate.opsForValue().set(Contant.COMMODITYWAREHOUSES_KEY, commodityWarehouseList,5,TimeUnit.MINUTES);
        redisTemplate.delete(Contant.COMMODITYWAREHOUSELIST_KEY);
        redisTemplate.opsForList().rightPushAll(Contant.COMMODITYWAREHOUSELIST_KEY, commodityWarehouseList);
        redisTemplate.expire(Contant.COMMODITYWAREHOUSELIST_KEY,5,TimeUnit.MINUTES);
        log.info("所有库房商品-------更新缓存数据");
    }

    @Async
    public void warehousedVoCache() {
        List<WarehousedVo> warehousedVoList;
        warehousedVoList = baseMapper.selectWarehousedVoList();
        redisTemplate.opsForValue().set(Contant.WAREHOUSEDVOS_KEY, warehousedVoList,5,TimeUnit.MINUTES);

        log.info("所有退货单-------更新缓存数据");

    }
}
